/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.formserver.viewmodel.util;


import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspEnumValue;
import com.inspur.edp.cef.designtime.api.variable.CommonVariable;
import com.inspur.edp.formserver.viewmodel.DotNetToJavaStringHelper;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.viewmodel.exception.VoModelErrorCodes;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UseTypeInfo;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnInfo;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.designtime.api.entity.enumtype.UseType;
import org.apache.cxf.common.util.CollectionUtils;

/**
 * 更新udt字段
 */
public class UpdateVoVariableUtil {

    /**
     * 根据引用的udt元数据更新字段(模板约束均更新)
     *
     * @param element
     * @param udt
     */
    public final void UpdateElementWithRefUdt(CommonVariable element, UnifiedDataTypeDef udt, boolean isFirstChoose) {
        element.setUdtID(udt.getId());
        element.setUdtName(udt.getName());

        // 其他属性
        if (udt instanceof ComplexDataTypeDef) {
            UpdateComplexDataTypeDefProperties(element, (ComplexDataTypeDef) udt);
        } else if (udt instanceof SimpleDataTypeDef) {
            UpdateSimpleDataTypeDefProperties(element, (SimpleDataTypeDef) udt, isFirstChoose);
        }
    }

    /**
     * 转换columnInfo为childElement
     *
     * @param info
     * @param prefix
     * @param ele    映射字段
     */
    public final void MapColumnInfoToField(ColumnInfo info, String prefix, CommonVariable ele) {
    }

    ///#region 单值

    /**
     * 根据单值udt更新字段的其他属性
     *
     * @param element
     * @param sUdt
     * @param isFirstChoose 是否首次选择
     */
    private void UpdateSimpleDataTypeDefProperties(CommonVariable element, SimpleDataTypeDef sUdt, boolean isFirstChoose) {
        if (DotNetToJavaStringHelper.isNullOrEmpty(element.getCode())) {
            element.setCode(sUdt.getCode());
        }
        if (DotNetToJavaStringHelper.isNullOrEmpty(element.getName())) {
            element.setName(sUdt.getName());
        }

        if (isFirstChoose || IsConstraint(sUdt, "DataType")) {
            element.setMDataType(sUdt.getMDataType());
        }
        if (isFirstChoose || IsConstraint(sUdt, "Length")) {
            element.setLength(sUdt.getLength());
        }
        if (isFirstChoose || IsConstraint(sUdt, "Precision")) {
            element.setPrecision(sUdt.getPrecision());
        }
        if (isFirstChoose || IsConstraint(sUdt, "ObjectType")) {
            element.setObjectType(sUdt.getObjectType());
            // 关联
            if (element.getChildAssociations() == null) {
                element.setChildAssociations(new GspAssociationCollection());
            }

            IGspCommonField belongElement = (!element.getChildAssociations().isEmpty()) ?
                    element.getChildAssociations().get(0).getBelongElement() : null;

            GspAssociationCollection assos = element.getChildAssociations().clone(belongElement);

            element.getChildAssociations().clear();
            if (!CollectionUtils.isEmpty(sUdt.getChildAssociations())) {
                throw new ViewModelException(VoModelErrorCodes.GSP_VIEWOBJECT_MODEL_1052, null);
            }

            element.setEnumIndexType(sUdt.getEnumIndexType());
            // 枚举
            element.getContainEnumValues().clear();
            if (sUdt.getContainEnumValues() != null && sUdt.getContainEnumValues().size() > 0) {
                for (GspEnumValue item : sUdt.getContainEnumValues()) {
                    element.getContainEnumValues().add(item);
                }
            }
        }
        if (isFirstChoose || IsConstraint(sUdt, "DefaultValue")) {
            element.setDefaultValue(sUdt.getDefaultValue().toString());
        }
        if (isFirstChoose || IsConstraint(sUdt, "IsRequired")) {
            element.setIsRequire(sUdt.getIsRequired());
        }
        // UnifiedDataType属性，前端根据[约束]/[模板]控制属性是否可编辑
        //element.UnifiedDataType = sUdt;
    }

    /**
     * 是否约束
     *
     * @return
     */
    private boolean IsConstraint(SimpleDataTypeDef sUdt, String propertyName) {
        if (sUdt.getPropertyUseTypeInfos().containsKey(propertyName)) {

            UseTypeInfo type = sUdt.getPropertyUseTypeInfos().get(propertyName);
            return type.getPropertyUseType() == UseType.AsConstraint;
        } else {
            throw new ViewModelException(VoModelErrorCodes.GSP_VIEWOBJECT_MODEL_1051, null, propertyName);
        }
    }


    ///#endregion


    ///#region 多值

    /**
     * 根据多值udt更新字段的其他属性
     *
     * @param element
     * @param cUdt
     */
    private void UpdateComplexDataTypeDefProperties(CommonVariable element, ComplexDataTypeDef cUdt) {
        if (ViewModelUtils.checkNull(element.getCode())) {
            element.setCode(cUdt.getCode());
        }
        if (DotNetToJavaStringHelper.isNullOrEmpty(element.getName())) {
            element.setName(cUdt.getName());
        }

        UdtElement newElement;
        if (cUdt.getElements().size() == 1 && cUdt.getDbInfo().getMappingType() != ColumnMapType.SingleColumn) {
            newElement = (UdtElement)cUdt.getElements().get(0);
        } else {
            newElement = new UdtElement(cUdt.getPropertys());
        }

        element.setObjectType(newElement.getObjectType());

        // 若为[单一列]的映射关系，可能导致超长，需把数据类型改为[Text]
        if (cUdt.getDbInfo().getMappingType() == ColumnMapType.SingleColumn) {
            element.setMDataType(GspElementDataType.Text);
            element.setLength(0);
            element.setPrecision(0);
        } else {
            element.setMDataType(newElement.getMDataType());
            element.setLength(newElement.getLength());
            element.setPrecision(newElement.getPrecision());
        }
        element.setDefaultValue(newElement.getDefaultValue());
        element.getChildAssociations().clear();
        element.getContainEnumValues().clear();
    }
}